package cloud.pangui.core.utils;

import cloud.pangui.core.exception.UtilsRuntimeException;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @Auther hepangui
 * @Date 2020/11/5 0005
 */
public class IpUtils {


	public static final Pattern ipv4Patten = Pattern.compile("(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])){3}");


	/**
	 * 校验是否是一个ip格式，ipv4
	 *
	 * @param ip
	 * @return ip 类型
	 */
	public static boolean validate(String ip) {
		if (ip == null) {
			return false;
		}
		return ipv4Patten.matcher(ip).matches();
	}

	public static String getRemoteIp(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if ((ip == null) || (ip.length() == 0) || (ip.equalsIgnoreCase("unknown"))) {
			ip = request.getHeader("X-Real-IP");
		}
		if ((ip == null) || (ip.length() == 0) || (ip.equalsIgnoreCase("unknown"))) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if ((ip == null) || (ip.length() == 0) || (ip.equalsIgnoreCase("unknown"))) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if ((ip == null) || (ip.length() == 0) || (ip.equalsIgnoreCase("unknown"))) {
			ip = request.getRemoteAddr();
		}
		if ((ip != null) && (ip.indexOf(",") >= 0)) {
			String[] ips = ip.split(",");
			ip = ips[(ips.length - 1)].trim();
		}
		return ip;
	}

	/**
	 * getRemotePort
	 *
	 * @param request
	 * @return
	 */
	public static int getRemotePort(HttpServletRequest request) {
		String port = request.getHeader("X-Forwarded-Port");
		if ((port == null) || (port.length() == 0) || (port.equalsIgnoreCase("unknown"))) {
			port = request.getHeader("X-Real-Port");
		}
		if ((port == null) || (port.length() == 0) || (port.equalsIgnoreCase("unknown"))) {
			port = request.getHeader("Proxy-Client-Port");
		}
		if ((port == null) || (port.length() == 0) || (port.equalsIgnoreCase("unknown"))) {
			port = request.getHeader("WL-Proxy-Client-Port");
		}
		if ((port == null) || (port.length() == 0) || (port.equalsIgnoreCase("unknown"))) {
			return request.getRemotePort();
		}
		try {
			return Integer.parseInt(port);
		} catch (Exception e) {
		}
		return 0;
	}

	public static String getLocalIp() {
		String[] ips = getIPS();
		if (ips.length == 0) {
			return "";
		}
		return ips[0];
	}

	public static String[] getIPS() {
		List<String> ips = new LinkedList();
		try {
			Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
			InetAddress ip;
			while (netInterfaces.hasMoreElements()) {
				NetworkInterface ni = netInterfaces.nextElement();
				Enumeration<InetAddress> addresses = ni.getInetAddresses();
				while (addresses.hasMoreElements()) {
					ip = addresses.nextElement();
					if (!ip.isLoopbackAddress() && ip.getHostAddress().indexOf(':') == -1) {
						ips.add(ip.getHostAddress());
					}
				}
			}
			return ips.toArray(new String[]{});
		} catch (SocketException e) {
			throw new UtilsRuntimeException(e);
		}

	}

	/**
	 * 获取本机地址
	 * 格式： B4-2E-99-02-F4-D0
	 *
	 * @return
	 */
	public static String getLocalMac() {
		try {
			String mac = getLocalMac(InetAddress.getLocalHost());
			if (mac == null) {
				String ip = getLocalIp();
				if (ip != null) {
					InetAddress addr = InetAddress.getByName(ip);
					if (addr != null) {
						mac = getLocalMac(addr);
					}
				}
			}
			return mac;
		} catch (SocketException | UnknownHostException e) {
			throw new UtilsRuntimeException(e);
		}

	}

	private static String getLocalMac(InetAddress ia) throws SocketException {
		byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
		if (mac == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < mac.length; i++) {
			if (i != 0) {
				sb.append("-");
			}
			int t = mac[i] & 0xFF;
			String str = Integer.toHexString(t).toUpperCase();
			if (str.length() == 1) {
				sb.append("0" + str);
			} else {
				sb.append(str);
			}
		}
		return sb.toString();
	}

}
